home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_0_m.arj / INT14.ASM < prev    next >
Assembly Source File  |  1980-01-01  |  23KB  |  624 lines

  1.      PAGE  ,132
  2. ;
  3. ;  INTERRUPT DRIVEN REPLACEMENT FOR IBM BIOS INTERRUPT 14
  4. ;
  5. ;  WRITTEN BY BOB MURPHY, NOVEMBER 1984.
  6. ;
  7. ;  YOU MAY WANT TO CHANGE THE COMMUNICATION BUFFER SIZE FOR COM1 AND COM2
  8. ;  DEPENDING ON THE RECIEVE SPEED, AND TYPE OF COMMUNICATIONS YOU ARE
  9. ;  DOING. THE 2K BUFFER IS GOOD FOR MOST 1200 BAUD APPLICATIONS, BUT WILL
  10. ;  BE EXCESSIVELY BIG FOR HUMAN-SPEED COMMUNICATIONS. THIS WILL HANDLE
  11. ;  CONTINUOUS DATA TRANSFER AT 9600 BAUD, ASSUMING THE APPLICATION USING IT
  12. ;  CAN ALSO KEEP UP. YOU WILL WANT TO USE A LARGER BUFFER FOR HIGHER
  13. ;  SPEEDS IF YOU ARE DOING FILE TRANSFERS.
  14. ;
  15. ;  REDUCE THE COM2 BUFFERS TO A SINGLE BYTE IF THERE IS ONLY ONE COMM
  16. ;  CHANNEL ON YOUR PC. DO NOT REMOVE THEM ENTIRELY.
  17. ;
  18. ;
  19. ;
  20. ;  INPUT PARAMETERS ARE THE SAME AS THE REGULAR BIOS ROUTINES
  21. ;  FOR FUNCTIONS (AH) = 0 TO (AH) = 4
  22. ;
  23. ;  READ CHARACTER NOWAIT - AH = 5
  24. ;  WILL READ A CHARACTER IF ONE IS AVAILABLE, AND RETURN IMMEDIATLY. THE
  25. ;  STATUS BYTE IN THE AH MUST BE CHECKED BY THE USER. IF AH BIT 0 = 1, THEN
  26. ;  THE AL CONTAINS A VALID CHARACTER. IF THAT BIT IS OFF, THEN THE AL CON-
  27. ;  TAINS GARBAGE.
  28. ;
  29. ;
  30. ;
  31. ;  THE STATUS RETURNED IS A BIT DIFFERENT THAN THE IBM ROUTINE IN THAT
  32. ;  THE BREAK DETECT BIT (AH BIT 4) IS SET IF A COMM BUFFER OVERFLOW OCCURS.  THE
  33. ;  ERROR FLAGS DO NOT NECESSARILY APPLY TO THE CHARACTER BEING READ.  THEY MAY
  34. ;  HAVE BEEN SET BY A LATER ARRIVING CHARACTER.  IN SHORT, THE ERROR BITS IN THE
  35. ;  AH ARE NOT 'REAL TIME'. ANY TIME THE STATUS IS READ (ON ANY COMMAND) THE
  36. ;  AH ERROR BITS ARE RESET FOR THE NEXT TIME.
  37. ;
  38. ;  THE TX HOLD REG EMPTY BIT INDICATES THERE IS SPACE IN THE TX OUTPUT BUFFER
  39. ;  THE TX SHIFT REG EMPTY BIT IS USED BY THE OUTBOUND SEND ROUTINE TO DETERMINE
  40. ;  IF IT NEEDS TO SEND A CHARACTER TO INITIATE THE TRANSMISSION PROCESS. THIS
  41. ;  BIT IS NOT USED BY ANY SOFTWARE THAT I KNOW OF, AND YOU SHOULD NOT USE IT.
  42. ;
  43. ;
  44. ;
  45.      PAGE
  46.      INCLUDE MACROS.ASM
  47.      BEGINCOM INT14
  48.      JMP   INIT000           ;INITIALIZE VECTORS
  49. BAUDTABL LABEL WORD
  50.      DW    1047           ;110 BAUD
  51.      DW    768           ;150 BAUD
  52.      DW    384           ;300 BAUD
  53.      DW    192           ;600 BAUD
  54.      DW    96           ;1200 BAUD
  55.      DW    48           ;2400 BAUD
  56.      DW    24           ;4800 BAUD
  57.      DW    12           ;9600 BAUD
  58. ROUTINES LABEL WORD
  59.      DW    COMMAND0        ;INITIALIZE COMMUNICATIONS CHANNEL
  60.      DW    COMMAND1        ;TRANSMIT CHARACTER IN AL ACROSS CHANNEL
  61.      DW    COMMAND2        ;WAIT FOR CHARACTER, AND RETURN IN AL
  62.      DW    COMMAND3        ;RETURN STATUS WORD (2 BYTES)
  63.      DW    COMMAND4        ;RECIEVE CHARACTER NOWAIT
  64. MAXCMD     DW    ($-ROUTINES)/2       ;MAXIMUM COMMAND VALUE (MAX AH VALUE)
  65. RS232_BASE    EQU WORD PTR ES:0    ;ADDRESS OF RS232 BASE ADDR TBL IN SEG 40
  66. RS232_TIM_OUT EQU BYTE PTR ES:07CH ;RS232 TIME OUT VALUE IN LO CORE
  67.      PAGE
  68. COM0000: STI               ;INTERRUPTS BACK ON
  69.      PUSH  BX
  70.      PUSH  CX
  71.      PUSH  DX
  72.      PUSH  SI
  73.      PUSH  ES
  74.      PUSH  DS           ;SAVE WHAT WE CLOBBER
  75.      MOV   BX,CS
  76.      MOV   DS,BX           ;MAKE THIS SEGMENT ADDRESSABLE
  77.      MOV   SI,DX           ;RS232 CARD SELECT TO SI
  78.      SHL   SI,1           ;WORD OFFSET
  79.      MOV   BX,40H           ;ADDRESS OF BIOS CORE AREA
  80.      MOV   ES,BX           ;STASH IN DATA SEG
  81.      MOV   DX,RS232_BASE [SI]  ;GET RS232 BASE ADDRESS
  82.      OR    DX,DX           ;TEST FOR NO CARD PRESENT
  83.      JZ    COM0090           ;RETURN
  84.      MOV   BL,AH           ;GET COMMAND INTO 2 BYTES
  85.      SUB   BH,BH           ; IN THE BX REGISTER
  86.      CMP   BX,MAXCMD       ;IS IT A VALID COMMAND?
  87.      JGE   COM0090           ;NO-RETURN
  88.      SHL   BX,1           ;MULTIPLY BY 2 FOR TRUE INDEX VALUE
  89.      CALL  ROUTINES [BX]       ;CALL APPROPRIATE COMMAND
  90. ;
  91. ;  RETURN FROM INTERRUPT 14 - NORMAL OR ABEND
  92. ;
  93. COM0090:
  94.      POP   DS
  95.      POP   ES
  96.      POP   SI
  97.      POP   DX           ;RETURN FROM INT14
  98.      POP   CX
  99.      POP   BX
  100.      IRET
  101.      PAGE
  102. ;******************************************************************************
  103. ;
  104. ; INITIALIZE COMMUNICATIONS PORT
  105. ;
  106. ; DX HAS PORT ADDRESS, AH HAS PARMS. BITS 5-7 = BAUD RATE
  107. ; SI HAS CARD # (0-3)              3-4 = PARITY
  108. ;                       2  = # STOP BITS
  109. ;                      0-1 = # DATA BITS
  110. ;
  111. ;******************************************************************************
  112. COMMAND0 PROC  NEAR
  113.      MOV   AH,AL           ;SAVE INIT PARMS IN AH
  114.      ADD   DX,03           ;POINT TO LINE CONTROL REGISTER (xFB)
  115.      MOV   AL,80H           ;OPEN DIVISOR LATCH
  116.      OUT   DX,AL           ;SET DLAB = 1
  117. ;
  118. ;  DETERMINE BAUD RATE DIVISOR, AND PUT IT IN THE BX REG
  119. ;
  120.      MOV   BL,AH           ;BAUD RATE PARMS TO BL
  121.      MOV   CL,04           ;SHIFT VALUE
  122.      ROL   BL,CL           ;MOVE TO ALIGN
  123.      AND   BX,0EH           ;BX HAS INDEX INTO BAUD RATE DIVISOR TABLE
  124.      MOV   BX,BAUDTABL [BX]    ;GET DIVISOR VALUE TO BX REGISTER
  125. ;
  126. ; SET BAUD RATE IN THE 8250
  127. ;
  128.      SUB   DX,2           ;POINT TO DIVISOR LATCH MSB (xF9)
  129.      MOV   AL,BH           ;GET HI DIVISOR VALUE
  130.      OUT   DX,AL           ;STICK IN DIVISOR LATCH
  131.      DEC   DX           ;POINT TO DIVISOR LATCH LSB (xF8)
  132.      MOV   AL,BL           ;GET LOW ORDER DIVISOR VALUE
  133.      OUT   DX,AL           ;SAVE DIVISOR VALUE
  134. ;
  135. ; SET UP PARITY, STOP BITS, AND WORD LENGTH IN THE 8250
  136. ;
  137.      ADD   DX,3           ;POINT TO LINE CTRL REG  (xFB)
  138.      MOV   AL,AH           ;INPUT PARMS TO AL
  139.      AND   AL,00011111B       ;BAUD BITS OFF
  140.      OUT   DX,AL           ;SET UP LCR, CLOSE DIVISOR LATCH
  141. ;
  142. ;  ENABLE THE 8250 INTERRUPTS
  143. ;
  144.      INC   DX           ;POINT TO MODEM CTRL REG (xFC)
  145.      MOV   AL,00001101B       ;SET UP OUT 2, DSR, AND RTS
  146.      OUT   DX,AL           ;ENABLE OUT 2 ON MCR (RQD FOR INTS)
  147.      SUB   DX,3           ;POINT TO INT ENABLE REGISTER (xF9)
  148.      MOV   AL,00001111B       ;ENABLE ALL INTERRUPTS
  149.      OUT   DX,AL           ;PROGRAM THE IER
  150. ;
  151. ; ELIMINATE ANY PENDING INTS BEFORE IRQ CHANNEL ENABLE
  152. ;
  153.      DEC   DX           ;POINT TO RX REGISTER (xF8)
  154.      IN    AL,DX           ;KILL ANY RECIEVE INTERRUPT
  155.      INC   DX
  156.      INC   DX           ;POINT TO IIR (xFA)
  157.      IN    AL,DX           ;KILL ANY THRE INTS
  158.      ADD   DX,3           ;POINT TO LINE STATUS REG (xFD)
  159.      IN    AL,DX           ;KILL LINE STATUS INTERRUPTS
  160.      INC   DX           ;POINT TO MSR (xFE)
  161.      IN    AL,DX           ;KILL MODEM STATUS INTERRUPTS
  162.      AND   AL,11110000B       ;KEEP THE MODEM STATUS BITS
  163.      MOV   COM1MODM [SI],AL    ;ISR STATUS REFLECTS REAL WORLD
  164.      MOV   AL,60H           ;SET UP THRE,TSRE STATUS
  165.      MOV   COM1LINE [SI],60H   ;SET LINE STATUS BITS
  166. ;
  167. ; RESET BUFFER POINTERS BEFORE IRQ INITIALIZATION
  168. ;
  169.      MOV   BX,COM1STRT [SI]    ;GET START OF BUFFER (IN) POINTER
  170.      MOV   COM1SPTR [SI],BX    ;START POINTER RESET
  171.      MOV   COM1EPTR [SI],BX    ;END POINTER RESET
  172.      MOV   BX,OUT1STRT [SI]    ;GET START OF BUFFER (OUT) POINTER
  173.      MOV   OUT1SPTR [SI],BX    ;START POINTER RESET
  174.      MOV   OUT1EPTR [SI],BX    ;END POINTER RESET
  175. ;
  176. ;  ENABLE THE IRQ CHANNEL ON THE 8259 INTERRUPT CONTROLLER
  177. ;
  178.      MOV   CX,SI           ;GET THE ADAPTER INVOLVED
  179.      SHR   CL,1           ;MAKE VALUE 0 OR 1
  180.      NEG   CL           ;MAKE 0 OR -1 (-1 = COM2)
  181.      ADD   CL,4           ;SET SHIFT COUNT TO 3 OR 4 (COM1=4)
  182.      MOV   AH,0FEH           ;SET UP MASK
  183.      ROL   AH,CL           ;ALIGN FOR INTERRUPT ENABLE ON 8259
  184.      CLI               ;STOP INTS WHILE WE SCREW W/8259
  185.      IN    AL,21H           ;GET CURRENT INTERRUPT MASK BYTE
  186.      AND   AL,AH           ;ENABLE THE 8259 INTERRUPT
  187.      OUT   21H,AL           ;RIGHT NOW
  188.      STI               ;INTS BACK ON, COM1 OR 2 IS ACCEPTING
  189. ;
  190. ;  RETURN FULL (2 BYTE) STATUS INFORMATION
  191. ;
  192.      CALL  COMMAND3        ;DO A FULL STATUS REQUEST
  193.      RET               ;AND WERE DONE
  194. COMMAND0 ENDP
  195.      PAGE
  196. ;******************************************************************************
  197. ;
  198. ; SEND CHARACTER IN AL OVER COM LINE (DTR AND CTS ARE SET ON)
  199. ;
  200. ;******************************************************************************
  201. COMMAND1 PROC  NEAR
  202.      MOV   BH,AL           ;SAVE INCOMING CHARACTER
  203. ;
  204. ;    TURN ON DTR AND CTS IF THEY ARE OFF
  205. ;
  206.      ADD   DX,4           ;POINT TO MODEM CONTROL REGISTER (xFC)
  207.      IN    AL,DX           ;GET CURRENT MCR CONTENTS
  208.      OR    AL,03           ;INSURE DTR AND RTS ARE ON
  209.      OUT   DX,AL           ;SEND BACK TO MCR
  210. ;
  211. ;    CHECK DSR AND RTS FROM OTHER END
  212. ;
  213.      MOV   AH,80H           ;ASSUME A TIME OUT WILL OCCUR
  214.      CALL  WAITDSR           ;WAIT FOR DSR AND CTS FROM THE OTHER END
  215.      JC    COM0295           ;DSR OR CTS NOT READY - GO ERROR
  216.      MOV   BL,RS232_TIM_OUT [SI] ;GET TIME OUT VALUE FOR THIS PORT
  217.      SUB   CX,CX           ;DELAY
  218. COM0220: TEST  COM1LINE [SI],20H   ;SPACE AVAIL IN BUFFER?
  219.      JNZ   COM0230           ;YES-GO SEND THE CHARACTER
  220.      LOOP  COM0220           ;ELSE-WAIT ON THE ISR TO GIVE US SOME ROOM
  221.      DEC   BL           ;DEC TIME OUT COUNT
  222.      JNZ   COM0220           ;AND CONTINUE TO WAIT FOR XMIT
  223.      JMP   SHORT COM0295       ;FALL THRU = TIME OUT ERROR
  224. COM0230: MOV   AL,BH           ;RESTORE CHARACTER IN AL
  225. ;
  226.      CLI               ;WERE GONNA TALK, SO DONT INTERRUPT
  227.                    ;THIS WILL HOLD OFF THE LAST THRE INT
  228.      TEST  COM1LINE [SI],40H   ;IS THE INTERRUPT ROUTINE RUNNING
  229.      JNZ   COM0260           ;NO-TRANSMIT THE CHARACTER IN THIS RTN
  230. ;                   ;=40=TX BUFFER COMPLETLY EMPTY
  231. ;
  232. ; THE XMIT ISR IS GOING, BUFFER THE CHARACTER
  233. ;
  234.      MOV   BX,OUT1EPTR [SI]    ;GET END OF BUFFER POINTER
  235.      MOV   [BX],AL           ;QUEUE UP THE CHARACTER FOR TRANSMISSION
  236.      INC   BX           ;POINT TO NEXT AVL CHAR POS
  237.      CMP   BX,OUT1ENDB [SI]    ;POINTING OFF THE END?
  238.      JNE   COM0240           ;NO-DONT REPOSITION
  239.      MOV   BX,OUT1STRT [SI]    ;ELSE-RESET TO BEGINNING OF BUFFER
  240. COM0240: CMP   BX,OUT1SPTR [SI]    ;BUFFER OVERRUN OCCUR?
  241.      JNE   COM0250           ;NO-THEN WERE OK
  242.      OR    COM1LINE,20H       ;POST BUFFER FULL FLAG
  243. COM0250: STI               ;WERE DONE-SO RESTORE INTERRUPTS
  244.      MOV   OUT1EPTR [SI],BX    ;SET BUFFER POSITION FOR NEXT CHARACTER
  245.      JMP   SHORT COM0290       ;RESTORE INTS AND RETURN
  246. ;
  247. ; THE XMIT ISR IS NOT GOING, SO WE WILL SEND A CHARACTER TO START IT UP
  248. ;
  249. COM0260:
  250.      AND   COM1LINE [SI],10111111B    ;TURN OFF TX BUFFER EMPTY (STRT ISR)
  251.                    ;THIS IS THE SHIFT REG EMPTY BIT
  252.      STI               ;DONT NEED TO HOLD OFF INTS FOR THIS
  253.      SUB   DX,4           ;POINT TO XMIT HOLDING REGISTER (xF8)
  254.      OUT   DX,AL           ;PUT CHAR IN TX HOLD REG. INTERRUPT WILL
  255.                    ;OCCUR WHEN IT HAS BEEN SENT.
  256. COM0290: CALL  HALFSTAT        ;GET STATUS OF LINE
  257. COM0295: RET
  258. COMMAND1 ENDP
  259.      PAGE
  260. ;******************************************************************************
  261. ;
  262. ;  RECIEVE CHARACTER FROM COMM-WAIT FOR COMM READY
  263. ;
  264. ;******************************************************************************
  265. COMMAND2 PROC NEAR
  266.      MOV   BL,RS232_TIM_OUT [SI] ;GET TIME OUT VALUE
  267.      SUB   CX,CX
  268. COM0320: TEST  COM1LINE [SI],1       ;IS THERE A CHAR READY FLAG POSTED
  269.      JNZ   COM0340           ;YES-GET OUT OF KILL TIME LOOP
  270.      LOOP  COM0320           ;ELSE-WAIT ON CHARACTER
  271.      DEC   BL           ;DEC TIME OUT COUNT
  272.      JNZ   COM0320           ;AND KEEP TRYING
  273.      CALL  HALFSTAT        ;GET LINE STATUS
  274.      OR    AH,80H           ;SET TIME OUT ERROR ALSO
  275.      JMP   SHORT COM0390       ;FAIL WITH TIME OUT
  276. COM0340: CALL  COMMAND4        ;CALL RECIEVE CHARACTER NOWAIT
  277.      CALL  HALFSTAT        ;SET LINE STATUS FLAGS
  278. COM0390: AND   AH,10011110B       ;ONLY RETURN ERROR BITS
  279.      RET               ;RETURN WITH EITHER A CHARACTER OR AN ERROR
  280. COMMAND2 ENDP
  281.      PAGE
  282. ;******************************************************************************
  283. ;
  284. ;  COMM PORT STATUS REQUEST       BX GETS CLOBBERED
  285. ;
  286. ;******************************************************************************
  287. COMMAND3 PROC  NEAR
  288.      CLI               ;KILL RS232 INTERRUPTS
  289.      MOV   AL,COM1MODM [SI]    ;GET MODEM STATUS INTERRUPT DATA
  290.      MOV   BL,AL           ;SAVE MODEM STATUS DATA
  291.      AND   AL,10110000B       ;CLEAR THE DELTAS (AND STICKY RING INDICATOR)
  292.      MOV   COM1MODM [SI],AL    ;WE READ IT, SO WE CAN TURN OFF BITS
  293.      MOV   AH,COM1LINE [SI]    ;GET THE LINE STATUS FLAGS
  294.      MOV   BH,AH           ;COPY THEM
  295.      AND   BH,01100001B       ;KILL THE ERROR BITS (BUT DONT KILL RX AVL)
  296.      MOV   COM1LINE [SI],BH    ;SAVE CHANGE OF STATE IN CORE
  297.      STI               ;INTS OK NOW THAT FLAGS HAVE BEEN GOTTEN
  298.      MOV   AL,BL           ;RESTORE THE MODEM STATUS DATA
  299.      RET               ;AND RETURN TO CALLER
  300. COMMAND3 ENDP
  301. ;
  302. ; CALL HALFSTAT TO RETURN LINE STATUS FLAGS IN AH. BH GETS CLOBBERED
  303. ;
  304. HALFSTAT PROC  NEAR           ;TO GET LINE STATUS ONLY, COME HERE
  305.      CLI
  306.      MOV   AH,COM1LINE [SI]    ;GET THE LINE STATUS FLAGS
  307.      MOV   BH,AH           ;COPY THEM
  308.      AND   BH,01100001B       ;KILL THE ERROR BITS (BUT DONT KILL RX AVL)
  309.      MOV   COM1LINE [SI],BH    ;SAVE CHANGE OF STATE IN CORE
  310.      STI               ;INTS OK NOW THAT FLAGS HAVE BEEN GOTTEN
  311.      RET               ;AND RETURN TO CALLER
  312. HALFSTAT ENDP
  313. ;
  314. ; WAIT FOR DSR AND RTS FROM THE OTHER END - IF TIME OUT, RETURN CARRY SET
  315. ;
  316. WAITDSR  PROC  NEAR
  317.      MOV   BL,RS232_TIM_OUT [SI] ;GET TIME OUT VALUE
  318.      SUB   CX,CX           ;LOOP VALUE
  319. WAIT100: MOV   AL,COM1MODM [SI]    ;GET MODEM STATUS INTERRUPT DATA
  320.      AND   AL,30H           ;IS DSR AND CTS ON?
  321.      CMP   AL,30H
  322.      JE    WAIT200           ;YES-RETURN NORMAL
  323.      LOOP  WAIT100           ;ELSE - TRY AGAIN
  324.      DEC   BL           ;DEC TIME OUT COUNTER
  325.      JNZ   WAIT100           ;AND TRY 65536 MORE TIMES
  326.      STC               ;FALL THRU = TIME OUT
  327. WAIT200: RET               ;RETURN TO CALLER
  328. WAITDSR  ENDP
  329.      PAGE
  330. ;*******************************************************************************
  331. ;
  332. ;  RETRIEVE CHARACTER FROM INTERRUPT BUFFER
  333. ;
  334. ;
  335. ;  RECIEVE CHARACTER NOWAIT. WILL RETURN CHARACTER IN AL IF ONE IS AVAILABLE.
  336. ;  THE STATUS BYTE IN AH SHOULD BE TESTED FOR A X'01' TO SEE IF A CHARACTER WAS
  337. ;  READ. IF BIT OFF, THEN AL  =  GARBAGE
  338. ;
  339. ;*******************************************************************************
  340. COMMAND4 PROC  NEAR
  341.      CLI               ;DONT ALLOW RS232 INTS WHILE WE READ
  342.      MOV   AH,COM1LINE [SI]    ;GET COMM STATUS FLAG
  343.      AND   COM1LINE [SI],61H   ;AND ERASE ANY ERRS. LEAVE DATA AVL ALONE
  344.      MOV   BX,COM1SPTR [SI]    ;GET START OF BUFFER POINTER
  345.      CMP   BX,COM1EPTR [SI]    ;SAME AS END OF BUFFER POINTER?
  346.      JE    COM0560           ;IF NO CHARS - KILL DATA AVL FLAG
  347. ;
  348. ;  GET A CHARACTER FROM THE BUFFER
  349. ;
  350. COM0540:
  351.      MOV   AL,[BX]           ;GET A CHARACTER FROM THE COMM BUFFER
  352.      INC   BX           ;
  353.      CMP   BX,COM1ENDB [SI]    ;OFF THE END?
  354.      JNE   COM0550           ;NO-DONT RESET
  355.      MOV   BX,COM1STRT [SI]    ;ELSE-PICK UP START OF BUFFER ADDRESS
  356. COM0550: MOV   COM1SPTR [SI],BX    ;SAVE UPDATED BUFFER POINTER
  357.      CMP   BX,COM1EPTR [SI]    ;DID WE JUST REMOVE THE LAST CHARACTER
  358.      JNE   COM0580           ;NO-DONT KILL DATA AVAILABLE
  359. ;
  360. ; BUFFER CLEARED OUT - KILL THE DATA AVAILABLE FLAG
  361. ;
  362. COM0560: AND   COM1LINE [SI],0FEH  ;ELSE-BUFFER EMPTY, DATA AVL OFF
  363.      AND   AH,0FEH           ;DO IN RETURN REG ALSO
  364. ;
  365. ;  CHAR READ, IF ANY - SO ITS MILLER TIME FOR THIS ROUTINE
  366. ;
  367. COM0580: STI               ;RE-ALLOW INTS
  368.      RET               ;AND HEAD OUT THE DOOR W/CHAR IN AL
  369. COMMAND4 ENDP
  370.      PAGE
  371.      ORG   0400H
  372. ;*COMMISR**********************************************************************
  373. ;
  374. ; RS232 INTERRUPT HANDLER
  375. ;
  376. ;******************************************************************************
  377. ;
  378. ;  POINTERS AND FLAGS FOR COMM BUFFERS
  379. ;
  380. COM1SPTR DW    COM1BUF           ;START OF COMM BUFFER 1
  381. COM2SPTR DW    COM2BUF           ;START OF COMM BUFFER 2
  382. ;
  383. COM1EPTR DW    COM1BUF           ;END POINTER FOR COMM BUFFER 1
  384. COM2EPTR DW    COM2BUF           ;END POINTER FOR COMM BUFFER 2
  385. ;
  386. COM1STRT DW    OFFSET COM1BUF       ;ADDRESS OF COM1 BUFFER START
  387. COM2STRT DW    OFFSET COM2BUF       ;ADDRESS OF COM2 BUFFER START
  388. ;
  389. COM1ENDB DW    OFFSET COM1END       ;ADDRESS OF COM1 BUFFER END
  390. COM2ENDB DW    OFFSET COM2END       ;ADDRESS OF COM2 BUFFER END
  391. ;
  392. OUT1SPTR DW    OUT1BUF           ;START OF OUTPUT COMM BUFFER 1
  393. OUT2SPTR DW    OUT2BUF           ;START OF OUTPUT COMM BUFFER 2
  394. ;
  395. OUT1EPTR DW    OUT1BUF           ;END POINTER FOR OUT COMM BUFFER 1
  396. OUT2EPTR DW    OUT2BUF           ;END POINTER FOR OUT COMM BUFFER 2
  397. ;
  398. OUT1STRT DW    OFFSET OUT1BUF       ;ADDRESS OF OUTPUT COM1 BUFFER START
  399. OUT2STRT DW    OFFSET OUT2BUF       ;ADDRESS OF OUTPUT COM2 BUFFER START
  400. ;
  401. OUT1ENDB DW    OFFSET OUT1END       ;ADDRESS OF COM1 OUTPUT BUFFER END
  402. OUT2ENDB DW    OFFSET OUT2END       ;ADDRESS OF COM2 OUTPUT BUFFER END
  403.      PAGE
  404. COM1LINE DB    60H           ;LINE STAT FOR COMM BUFFER 1
  405. ;                     80 = TIME OUT (USED BY RD/WRT RTN)
  406. ;                     40 = TSRE =1= LAST CHAR HAS BEEN SENT
  407. ;                      AND THE TX BUFFER IS EMPTY
  408. ;                     20 = THRE =1= SPACE AVAILABLE IN TX BUF
  409. ;                     10 = BREAK DETECT/BUFFER OVERFLOW
  410. ;                     08 = FRAMING ERROR
  411. ;                     04 = PARITY ERROR
  412. ;                     02 = OVERRUN ERROR
  413. ;                     01 = DATA AVAILABLE
  414. COM1MODM DB    0           ;MODEM STATUS BYTE FOR COM1
  415. ;                     80 = RLSD (CARRIER DETECT)
  416. ;                     40 = RING INDICATOR
  417. ;                     20 = DATA SET READY
  418. ;                     10 = CLEAR TO SEND
  419. ;                     08 = DELTA RLSD (CARRIER DETECT)
  420. ;                     04 = DELTA RING INDICATOR
  421. ;                     02 = DELTA DATA SET READY
  422. ;                     01 = DELTA CLEAR TO SEND
  423. COM2LINE DB    60H           ;LINE STAT FOR COMM BUFFER 2
  424. COM2MODM DB    0           ;MODEM STATUS BYTE FOR COM2
  425. ;
  426. COMMBASE DW    0           ;STARTING I/O ADDRESS FOR COMM CARD
  427. ;
  428. ;  INPUT BUFFER FOR COMM CHANNEL 1
  429. ;
  430. COM1BUF  DW    2048 DUP (?)
  431. COM1END  EQU   $
  432. ;
  433. ;  INPUT BUFFER FOR COMM CHANNEL 2
  434. ;
  435. COM2BUF  DW    2048 DUP (?)
  436. COM2END  EQU   $
  437. ;
  438. ; OUTPUT BUFFER FOR COMM CHANNEL 1
  439. ;
  440. OUT1BUF  DW    256 DUP (?)
  441. OUT1END  EQU   $
  442. ;
  443. ; OUTPUT BUFFER FOR COMM CHANNEL 2
  444. ;
  445. OUT2BUF  DW    256 DUP (?)
  446. OUT2END  EQU   $
  447.      PAGE
  448. ;
  449. ;  INTERRUPT SERVICE ROUTINES FOR COM1 AND COM2
  450. ;
  451. ISRTABLE LABEL WORD           ;INTERRUPT SERVICE ROUTINE ADDR TABLE
  452.      DW    ISRMODEM        ;MODEM STATUS ROUTINE (PRI 4)
  453.      DW    ISRXMIT           ;XMIT DATA (PRI 3)
  454.      DW    ISRRECV           ;RECIEVE DATA (PRI 2)
  455.      DW    ISRLINE           ;LINE STATUS (PRI 1)
  456.  
  457. ISR1000: STI               ;ALLOW OTHER INTERRUPTS
  458.      PUSH  SI
  459.      MOV   SI,0           ;INDICATE COMM CARD 1
  460.      JMP   SHORT ISR0100       ;SKIP TO MAINLINE
  461. ISR2000: STI               ;ALLOW OTHER INTERRUPTS
  462.      PUSH  SI
  463.      MOV   SI,2           ;INDICATE COMM CARD 2
  464. ;
  465. ;  MAINLINE INTERRUPT RTN
  466. ;
  467. ISR0100: PUSH  AX           ;SAVE ALL REGS USED
  468.      PUSH  BX
  469.      PUSH  CX
  470.      PUSH  DX
  471.      PUSH  DS
  472. ;
  473. ; SET UP BASE REGISTERS
  474. ;
  475.      MOV   AX,40H           ;ADDRESS OF RS232 CARD I/O PORT ADDRESSES
  476.      MOV   DS,AX           ;DS = CS FOR DATA BUFFERS
  477.      MOV   DX,WORD PTR [SI]    ;GET COMM CARD BASE ADDRESS
  478.      MOV   AX,CS
  479.      MOV   DS,AX           ;DS POINTS TO PGM FOR USE OF COMM BUFFERS
  480.      MOV   COMMBASE,DX       ;SAVE COMM CARD BASE FOR SECOND TIME THROUGH
  481. ISR0120: MOV   DX,COMMBASE       ;GET STARTING I/O ADDRESS FOR COMM CARD
  482.      INC   DX
  483.      INC   DX           ;GET PORT FOR INT IDENTIFICATION REG
  484.      IN    AL,DX           ;GET IIR CONTENTS
  485.      TEST  AL,1           ;IS AN INTERRUPT PENDING?
  486.      JNZ   ISR0140           ;NO-EOI TO 8259 & LEST GET OUT OF HERE
  487.      CBW               ;ELSE-GET INDEX INTO TABLE
  488.      MOV   BX,AX           ;COPY TO USEFUL REGISTER
  489.      CALL  ISRTABLE [BX]       ;CALL APPROPRIATE ROUTINE
  490.      JMP   ISR0120           ;AND KEEP CHECKING UNTIL ALL INTS DONE
  491. ISR0140:
  492. ;
  493. ;      SIGNAL END OF INTERRUPT TO 8259
  494. ;
  495.      CLI               ;KILL INTERRUPTS
  496.      MOV AL,20H           ;NON-SPECIFIC EOI
  497.      OUT 20H,AL           ;SEND IT
  498.      STI               ;RE-ALLOW INTERRUPTS
  499. ;
  500. ;  END OF INTERRUPT CODE
  501. ;
  502.      POP   DS
  503.      POP   DX
  504.      POP   CX
  505.      POP   BX
  506.      POP   AX
  507.      POP   SI
  508.      IRET
  509.      PAGE
  510. ;**ISRLINE*********************************************************************
  511. ;
  512. ;  LINE STATUS ERROR HANDLER
  513. ;
  514. ;******************************************************************************
  515. ISRLINE  PROC  NEAR
  516.      ADD   DX,3           ;LINE STATUS REGISTER (xFD)
  517.      IN    AL,DX           ;GET STATUS
  518.      AND   AL,00011110B       ;MASK NON-ERROR BITS
  519.      OR    COM1LINE [SI],AL    ;AND SAVE IN COMM FLAGS
  520.      RET
  521. ISRLINE  ENDP
  522.  
  523.  
  524.  
  525. ;**ISRRECV*********************************************************************
  526. ;
  527. ;  INBOUND CHARACTER INTERRUPT SERVICE ROUTINE
  528. ;
  529. ;******************************************************************************
  530. ISRRECV  PROC  NEAR
  531. ;
  532. ; GET INCOMING CHARACTER AND BUFFER IT
  533. ;
  534.      DEC   DX
  535.      DEC   DX           ;RECEIVE BUFFER REGISTER (xF8)
  536.      SUB   AH,AH           ;SET FLAGS = 0
  537.      IN    AL,DX           ;GET INPUT CHARACTER
  538.      MOV   BX,COM1EPTR [SI]    ;COM-BUF END POINTER
  539.      MOV   DX,BX           ;SAVE POINTER BEFORE INCREMENT
  540.      INC   BX           ;BUMP POINTER
  541.      CMP   BX,COM1ENDB [SI]    ;PAST END?
  542.      JNE   ISR0220           ;JUMP IF NOT
  543.      MOV   BX,COM1STRT [SI]    ;ELSE POINT TO START
  544. ISR0220: CMP   BX,COM1SPTR [SI]    ;OVERFLOW IF HEAD = TAIL
  545.      JE    ISR0240           ;OVERFLOW
  546.      MOV   COM1EPTR [SI],BX    ;AND NEW INPUT POINTER
  547.      MOV   BX,DX           ;GET UNBUMPED POINTER BACK
  548.      MOV   [BX],AL           ;NO OVERFLOW, SAVE CHAR IN COM1BUF
  549.      OR    AH,1
  550.      JMP   ISR0280           ;WERE ALL DONE RECIEVING CHARACTER
  551. ISR0240: OR    AH,10H           ;SET OVERFLOW/BREAK FLAG
  552. ISR0280: OR    COM1LINE [SI],AH    ;PUT IN LINE STATUS FIELD
  553.      RET
  554. ISRRECV  ENDP
  555.      PAGE
  556. ;**ISRXMIT*********************************************************************
  557. ;
  558. ;  OUTBOUND CHARACTER INTERRUPT SERVICE ROUTINE
  559. ;
  560. ;  POST XMIT SHIFT REG EMPTY WHEN LAST CHAR PLACED IN XMIT HOLD REG.
  561. ;  KILL XMIT HOLD REG EMPTY WHEN XMIT BUFFER IS FILLED UP
  562. ;
  563. ;******************************************************************************
  564. ISRXMIT  PROC  NEAR
  565. ;
  566.      MOV   AH,40H           ;ASSUME WE WILL SEND LAST CHARACTER
  567.      MOV   BX,OUT1SPTR [SI]    ;GET START OF BUFFER POINTER
  568.      CMP   BX,OUT1EPTR [SI]    ;IS THE BUFFER EMPTY?
  569.      JE    ISR0480           ;YES-SKIP THE DATA TRANSMISSION
  570.      DEC   DX
  571.      DEC   DX           ;POINT TO XMIT HOLDING REGISTER (xF8)
  572.      MOV   AL,[BX]           ;GET CHARACTER FROM BUFFER
  573.      OUT   DX,AL           ;SEND IT ON ITS WAY
  574.      INC   BX           ;BUMP THE OUTPUT BUFFER POINTER
  575.      CMP   BX,OUT1ENDB [SI]    ;POINTING AT THE END OF THE BUFFER
  576.      JNE   ISR0420           ;NO-POINTER IS OK
  577.      MOV   BX,OUT1STRT [SI]    ;ELSE - POINT TO BUFFER START
  578. ISR0420: MOV   OUT1SPTR [SI],BX    ;SAVE NEW BUFFER POINTER
  579.      OR    AH,20H           ;SEND BACK A TX HOLD REG EMPTY INDICATION
  580.      CMP   OUT1EPTR [SI],BX    ;DID WE JUST EMPTY THE BUFFER?       *T
  581.      JE    ISR0480           ;YES-THEN THERE WONT BE ANY MORE INTS   *T
  582.      AND   AH,10111111B       ;AND SET BIT SAYS WERE OPERATING
  583. ISR0480: OR    COM1LINE [SI],AH    ;STUFF IT IN THE FLAGS
  584.      RET
  585. ISRXMIT  ENDP
  586. ;**ISRMODEM********************************************************************
  587. ;
  588. ;  MODEM STATUS INTERRUPT SERVICE ROUTINE
  589. ;
  590. ;******************************************************************************
  591. ISRMODEM PROC  NEAR
  592.      ADD   DX,4           ;POINT TO MODEM STATUS REGISTER (xFE)
  593.      IN    AL,DX           ;GET CONTENTS & CLEAR INTERRUPT
  594.      MOV   AH,AL
  595.      AND   AH,11110000B       ;GET ACTUAL SIGNAL LINE STATUS
  596.      OR    AL,COM1MODM [SI]    ;OR IN PREVIOUS LINE STATUS
  597.      AND   AL,01001111B       ;GET DELTA VALUES ALONE
  598.                    ;AND LEAVE RING INDICATOR ON
  599.      OR    AL,AH           ;SEVERAL DELTA VALUES, BUT ONLY CURRENT
  600.      MOV   COM1MODM [SI],AL    ;  MODEM STATUS INTO MODEM STATUS FIELD
  601.      RET               ;AND WERE DONE
  602. ISRMODEM ENDP
  603. PRGMEND  EQU   $           ;END OF CODE TO SAVE IN CORE
  604.      PAGE
  605. ;**NONRES**********************************************************************
  606. ;
  607. ;  THE FOLLOWING IS NON-RESIDENT CODE
  608. ;
  609. ;******************************************************************************
  610. ;
  611. ;  PROGRAM INITIALIZATION
  612. ;
  613. INIT000: MOV   DX,OFFSET COM0000   ;POINT TO START OF ROUTINE
  614.      @DOS  25H,14H           ;RESET VECTOR 14
  615.      MOV   DX,OFFSET ISR1000   ;ADDRESS OF COM 1 HANDLER
  616.      CLI               ;STOP INTS DURING 8259 VECTOR UPDATE
  617.      @DOS  25H,0CH           ;RESET VECTOR 0C  (IRQ4-FOR COM1)
  618.      MOV   DX,OFFSET ISR2000   ;ADDRESS OF COM 2 HANDLER
  619.      @DOS  25H,0BH           ;RESET VECTOR 0B  (IRQ3-FOR COM2)
  620.      STI
  621.      MOV   DX,OFFSET PRGMEND   ;POINT TO END OF CODE TO KEEP FOREVER
  622.      INT   27H           ;TERMINATE & STAY RESIDENT
  623.      ENDCOM INT14
  624.